package lg.minecraft.plugin.cobblemoncore.util;

import com.cobblemon.mod.common.api.pokemon.PokemonProperties;
import com.cobblemon.mod.common.pokemon.Species;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

/**
 * @author langle__
 * @version 1.0
 */
public class PokemonPropertiesArgumentType {

    public static final PokemonPropertiesArgumentType INSTANCE = new PokemonPropertiesArgumentType();
    private static final String ASSIGNER = "=";

    private PokemonPropertiesArgumentType() {}

    @NotNull
    public PokemonProperties parse(@NotNull String... reader) {
        PokemonDataCache instance = PokemonDataCache.getInstance();
        StringBuilder builder = new StringBuilder();
        List<String> moveList = new ArrayList<>();
        for (String read : reader) {
            if (read.contains(ASSIGNER)) {
                String[] split = read.split(ASSIGNER, 2);
                String key = split[0];
                String value = split[1];
                if ("move".equals(key)) {
                    String[] temp = value.split(",");
                    for (String t : temp) {
                        moveList.add(instance.getMoveName(t));
                    }
                    continue;
                }
                String newValue = switch (key) {
                    case "ability" -> instance.getAbilityName(value);
                    case "nature" -> instance.getNatureName(value);
                    case "pokeball" -> instance.getPokeBallName(value);
                    case "gender" -> instance.getGenderName(value);
                    case "type", "elemental_type" -> instance.getElementalTypeName(value);
                    default -> null;
                };
                if (newValue == null) {
                    builder.append(key).append(ASSIGNER).append(value).append(" ");
                } else {
                    builder.append(key).append(ASSIGNER).append(newValue).append(" ");
                }
            } else {
                Species value = instance.getSpeciesByKey(read);
                builder.append(value == null ? read : value.showdownId()).append(" ");
            }
        }
        PokemonProperties properties = PokemonProperties.Companion.parse(builder.toString().trim());
        properties.setMoves(moveList);
        return properties;
    }

    @NotNull
    public PokemonProperties parse(@NotNull String reader) {
        return parse(reader.split(" "));
    }

    @NotNull
    public List<String> listSuggestions(String[] args) {
        if (args.length == 0) return List.of();

        List<String> list = new ArrayList<>();
        String arg = args[args.length - 1];
        if (args.length == 1) {
            if (arg.isEmpty()) {
                list.addAll(PokemonDataCache.getInstance().getSpeciesKeySet());
            } else {
                PokemonDataCache.getInstance().getSpeciesKeySet().stream().filter(name -> name.contains(arg)).forEachOrdered(list::add);
            }
        }

        if (arg.contains(ASSIGNER)) {
            String[] split = arg.split(ASSIGNER, 2);
            String key = split[0];
            String value = split[1];
            list.addAll(PokemonPropertyParamsSuggester.INSTANCE.suggestValues(key, value));
            return list;
        }

        List<String> excludedKeys = new ArrayList<>();
        for (int index = 0; index < args.length - 1; index++) {
            String temp = args[index];
            if (temp.contains(ASSIGNER)) {
                temp = temp.split(ASSIGNER, 2)[0];
            }
            excludedKeys.add(temp);
        }
        list.addAll(PokemonPropertyParamsSuggester.INSTANCE.suggestKeys(arg, excludedKeys));
        return list;
    }

}
